import os
import re
import subprocess
import time
import xml.etree.cElementTree as ET
from robot.api import logger
from time import sleep
CURRENT_PATH = os.path.split(os.path.realpath(__file__))[0]
XML_NAME = 'uidump.xml'
XMLPATH = os.path.join(CURRENT_PATH, XML_NAME)

#################################################################################################
#################################################################################################

def android_send_adbshell(cmd,devicesid=None):
    #下发adb shell 命令
    ret = ''
    if not cmd:
        raise Exception('The adbshell not find')
    if devicesid:
        cmd = cmd.replace('adb shell', 'adb -s {} shell'.format(devicesid))

    proc = subprocess.Popen(cmd, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    logger.info(cmd)
    timeout = 30
    t_beginning = time.time()
    seconds_passed = 0
    while True:
        if proc.poll() is not None:
            break
        seconds_passed = time.time() - t_beginning
        if seconds_passed > timeout:
            proc.terminate()
            raise Exception('the {} timeout'.format(cmd))
        time.sleep(0.1)
    ret = proc.stdout.read()
    proc.terminate()
    ret = ret.decode('utf-8')
    return ret

#################################################################################################
#################################################################################################
def android_get_devices(index=0):
    ''' *函数说明*: 获得当前连接设备的序列号
        *参数说明*:
            index  序列号获取索引  ...可选
        *example*:
            android_get_devices    
        *返回值*:
            返回deviceID设备序列号
    '''
    ret = android_send_adbshell('adb devices')
    b = re.findall('(\w+)\s+device\s', ret)
    if len(b) == 1:
        return b[index]
    elif len(b) > 1:
        return b[index]
    else:
        raise Exception('The devices not find,please check adb devices')

#################################################################################################
#################################################################################################
def android_get_uidumpxml(devicesid=None):
    ''' *函数说明*: 获得手机当前界面的UI信息，生成uidump.xml
        *参数说明*:
            devicesid  设备序列号  ...可选
        *example*:
            android_get_uidumpxml    c08c1b39
        *返回值*:
            uidump.xml本地存放路径
    '''
    xmlpath = os.path.join(CURRENT_PATH, XML_NAME)
    if os.path.exists(xmlpath):
        os.remove(xmlpath)
    ret = ''
    ret = android_send_adbshell('adb shell uiautomator dump /data/local/tmp/uidump.xml',devicesid)
    if 'UI hierchary dumped to' not in ret:
        raise Exception('adb shell uiautomator dump /data/local/tmp/uidump.xml fail!!!')
    ret = android_send_adbshell('adb -s {} pull /data/local/tmp/uidump.xml {}'.format(devicesid,CURRENT_PATH))
    if os.path.exists(xmlpath):
        return  xmlpath
    else:
        raise Exception('put xml to {} fail!!!!'.format(CURRENT_PATH))

#################################################################################################
#################################################################################################
def android_get_coordinate(tag):
    ''' *函数说明*: 得到对应元素坐标
        *参数说明*:
            tag  元素名称  ...必选
        *example*:
            android_get_coordinate    wlan
        *返回值*:
            元素横纵坐标
    '''
    try: 
        tree = ET.ElementTree(file=XMLPATH)
        root = tree.getroot() # 获取根节点 <Element 'data' at 0x02BF6A80>
        # 遍历xml文档的第二层,遍历root可以得到元素node
        for element in root.iter("node"):
            #查看所有元素，定位调试时使用
            #logger.info('element.attrib: {}'.format(element.attrib))
            if element.attrib['text'].lower()== tag.lower():
                bounds = element.attrib['bounds'] #bounds坐标
                a = re.findall('\[(\d+),(\d+)\]\[(\d+),(\d+)\]',bounds)[0]
                logger.info('tag is : %s,coordinate is %s' % (tag,a))
                Xpoint = int(a[0]) + (int(a[2]) - int(a[0])) / 2
                Ypoint = int(a[1]) + (int(a[3]) - int(a[1])) / 2
                return Xpoint,Ypoint
    except Exception as e:
            logger.info("android_get_coordinate with error:%s" % e, True, True)

#################################################################################################
#################################################################################################
def android_input_tap(Xpoint=None , Ypoint=None , devicesid=None):
    ''' *函数说明*: 点击坐标对应位置

        *参数说明*:
            Xpoint  横坐标           ...必选
            Ypoint  纵坐标           ...必选
            devicesid  设备序列号     ...可选
        adb shell input tap 500.0 300.0
        *example*:
            android_input_tap    500.0  300.0
    '''
    if not Xpoint or not Ypoint:
        raise Exception('please input Xpoint and Ypoint')
    android_send_adbshell('adb shell input tap {} {}'.format(Xpoint,Ypoint),devicesid)

#################################################################################################
#################################################################################################
def android_input_swipe(FrontXpoint=None , FrontYpoint=None , NowXpoint=None , NowYpoint=None ,devicesid=None):
    ''' *函数说明*: 滑动屏幕

        *参数说明*:
            FrontXpoint  横坐标(移动前)           ...必选
            FrontYpoint  纵坐标(移动前)            ...必选
            NowXpoint    横坐标   (移动后)         ...必选
            FrontYpoint  纵坐标 (移动后)           ...必选
            NowYpoint  设备序列号     ...可选
        adb shell input swipe 500 1000 500 500 500      最后一个500位时间(ms)
        *example*:
            android_input_swipe    1000  500  500  500
    '''
    android_send_adbshell('adb shell input swipe {} {} {} {} 500'.format(FrontXpoint,FrontYpoint,NowXpoint,NowYpoint),devicesid)

#################################################################################################
#################################################################################################
def android_input_text(text=None, devicesid=None):
    ''' *函数说明*: 在输入框输入内容

        *参数说明*:
            text  输入内容           ...必选
            deviceid  设备序列号     ...可选
        adb shell input text FYX
        *example*:
            android_input_text    FYX
    '''
    if not text:
        raise Exception('please input text')
    android_send_adbshell('adb shell input text {}'.format(text),devicesid)

#################################################################################################
#################################################################################################
def android_input_KEYCODE(keyevent=None, devicesid=None):
    ''' *函数说明*: 根据KEYCODE值下发

        *参数说明*:
            keyevent  KEYCODE值           ...必选
                按键Home-------3
                唤醒屏幕-------26
                回车键---------66
                更多可查adb shell KEYCODE表
            devicesid  设备序列号     ...可选
        adb shell input keyevent 3
        *example*:
            android_input_KEYCODE    3
    '''
    if not keyevent:
        raise Exception('please input keyevent')
    android_send_adbshell('adb shell input keyevent {}'.format(keyevent),devicesid)

